welo git mirrors
src/relay.rs 7eec35ad5473bb3ef44f8d33a6ecdfc7c4c7c215 (7eec35ad) Text, 15.41 KB
T8b949e//! Bidirectional TCP?UDP ↔ RNS relay — used by both client and server sessions.
T8b949e//!
T8b949e//! Dev Note 1, idk where to put this but the buffer could be smaller than
Tff7b72use Te6edf3std::Te6edf3net::Te6edf3Ipv4AddrTb4b4b4;
Tff7b72use Te6edf3std::Te6edf3sync::Te6edf3ArcTb4b4b4;
Tff7b72use Te6edf3fast_socks5::Tb4b4b4{Te6edf3new_udp_headerTb4b4b4, Te6edf3parse_udp_requestTb4b4b4}Tb4b4b4;
Tff7b72use Te6edf3fast_socks5::Te6edf3util::Te6edf3target_addr::Te6edf3ToTargetAddrTb4b4b4;
Tff7b72use Te6edf3log::Tb4b4b4{Te6edf3debugTb4b4b4, Te6edf3warnTb4b4b4}Tb4b4b4;
Tff7b72use Te6edf3tokio::Te6edf3io::Tb4b4b4{Te6edf3AsyncReadExtTb4b4b4, Te6edf3AsyncWriteExtTb4b4b4}Tb4b4b4;
Tff7b72use Te6edf3tokio::Te6edf3sync::Tb4b4b4{Te6edf3MutexTb4b4b4, Te6edf3mpscTb4b4b4}Tb4b4b4;
Tff7b72use Te6edf3udp_stream::Te6edf3UdpStreamTb4b4b4;
Tff7b72use Tff7b72crate::Te6edf3filter::Tb4b4b4{Te6edf3FilterConfigTb4b4b4, Te6edf3allowed_ipTb4b4b4, Te6edf3filter_and_convertTb4b4b4}Tb4b4b4;
Tff7b72use Tff7b72crate::Te6edf3frame::Tb4b4b4{Te6edf3FrameTb4b4b4, Te6edf3FrameTypeTb4b4b4}Tb4b4b4;
Tff7b72use Tff7b72crate::Te6edf3mux::Te6edf3MuxHandleTb4b4b4;
T8b949e/// Relay data bidirectionally between a TCP stream and an RNS mux session.
T8b949e///
T8b949e/// Sends a `Close` frame and drops the session when either direction finishes.
Tff7b72pub Tff7b72async Tff7b72fn Td2a8ffrelay_bidirectional_tcpTb4b4b4(
Te6edf3sid: Tffa657u32Tb4b4b4,
Te6edf3stream: T56d364tokio::Te6edf3net::Te6edf3TcpStreamTb4b4b4,
Te6edf3mux: T56d364MuxHandleTb4b4b4,
Tff7b72mut Te6edf3session_rx: T56d364mpsc::Te6edf3UnboundedReceiverTff7b72<Te6edf3FrameTff7b72>Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72let Tb4b4b4(Tff7b72mut Te6edf3tcp_readTb4b4b4, Tff7b72mut Te6edf3tcp_writeTb4b4b4) Tff7b72= Te6edf3streamTb4b4b4.Te6edf3into_splitTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3mux_fwd Tff7b72= Te6edf3muxTb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] relay bidirectional tcpTa5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4)Tb4b4b4;
T8b949e// TCP -> RNS
Tff7b72let Te6edf3tcp_to_rns Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72let Tff7b72mut Te6edf3buf Tff7b72= Tb4b4b4[T79c0ff0Tff7b72u8Tb4b4b4; T79c0ff4096Tb4b4b4]Tb4b4b4;
Tff7b72loop Tb4b4b4{
Tff7b72match Te6edf3tcp_readTb4b4b4.Te6edf3readTb4b4b4(Tff7b72&Tff7b72mut Te6edf3bufTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tffa657OkTb4b4b4(T79c0ff0Tb4b4b4) Tff7b72=Tff7b72> Tff7b72breakTb4b4b4,
Tffa657OkTb4b4b4(Te6edf3nTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3mux_fwdTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3DataTb4b4b4, Te6edf3sidTb4b4b4, Te6edf3bufTb4b4b4[Tff7b72..Te6edf3nTb4b4b4]Tb4b4b4.Te6edf3to_vecTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4}
Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] TCP read error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// RNS -> TCP
Tff7b72let Te6edf3rns_to_tcp Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72while Tff7b72let Tffa657SomeTb4b4b4(Te6edf3frameTb4b4b4) Tff7b72= Te6edf3session_rxTb4b4b4.Te6edf3recvTb4b4b4(Tb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tff7b72match Te6edf3frameTb4b4b4.Te6edf3frame_type Tb4b4b4{
Te6edf3FrameType::Te6edf3Data Tff7b72=Tff7b72> Tb4b4b4{
T8b949e// info!("{:?}", &frame.payload);
Tff7b72if Tff7b72let Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72= Te6edf3tcp_writeTb4b4b4.Te6edf3write_allTb4b4b4(Tff7b72&Te6edf3frameTb4b4b4.Te6edf3payloadTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] TCP write error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3FrameType::Te6edf3Close Tff7b72=Tff7b72> Tff7b72breakTb4b4b4,
Te6edf3FrameType::Te6edf3ConnectErr Tff7b72=Tff7b72> Tb4b4b4{Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ffconnection errored, should probably be handled by different codeTa5d6ff"Tb4b4b4)Tb4b4b4; Tff7b72breakTb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3tokio::Te6edf3selectTff7b72! Tb4b4b4{
Te6edf3_ Tff7b72= Te6edf3tcp_to_rns Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72= Te6edf3rns_to_tcp Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Tb4b4b4}
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] drop connectionTa5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4)Tb4b4b4;
Te6edf3muxTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3CloseTb4b4b4, Te6edf3sidTb4b4b4, Tffa657Vec::Te6edf3newTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Te6edf3muxTb4b4b4.Te6edf3drop_sessionTb4b4b4(Te6edf3sidTb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4}
T8b949e/// udp client side must be split off to due a lot of things
Tff7b72pub Tff7b72async Tff7b72fn Td2a8ffrelay_bidirectional_udp_client_sideTb4b4b4(
Te6edf3sid: Tffa657u32Tb4b4b4,
Te6edf3socket: T56d364tokio::Te6edf3net::Te6edf3UdpSocketTb4b4b4,
Te6edf3tcp_stream: T56d364tokio::Te6edf3net::Te6edf3TcpStreamTb4b4b4,
Te6edf3mux: T56d364MuxHandleTb4b4b4,
Tff7b72mut Te6edf3session_rx: T56d364mpsc::Te6edf3UnboundedReceiverTff7b72<Te6edf3FrameTff7b72>Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72let Te6edf3socket Tff7b72= Te6edf3Arc::Te6edf3newTb4b4b4(Te6edf3socketTb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3socket1 Tff7b72= Te6edf3socketTb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3mux_fwd Tff7b72= Te6edf3muxTb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3client_local_port_mutex Tff7b72= Te6edf3Mutex::Te6edf3newTb4b4b4(Tffa657NoneTb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3client_local_port_1 Tff7b72= Te6edf3Arc::Te6edf3newTb4b4b4(Te6edf3client_local_port_mutexTb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3client_local_port_2 Tff7b72= Te6edf3client_local_port_1Tb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// the socksv5 protocol never sends the port number that the
T8b949e// udp relay server should be expecting from the client, and the port number for the udp
T8b949e// connection may be different that the tcp port. So the only way to get the port that the client
T8b949e// is expecting is to wait until the client has sent data through udp and record that data
T8b949e// this does mean that if the client is only ever receiving data from udp, it will never get
T8b949e// the right port number because the relay will never know which port to send it through.
T8b949e// I reckon that situation is very rare and that most socksv5 clients will account for that
T8b949e// but it's possible this breaks here.
T8b949e//
T8b949e// I might just be being stupid but I can't find a better way of figuring this out. and the spec
T8b949e// is pretty vague so https://www.rfc-editor.org/info/rfc1928/
T8b949e//
T8b949e// you could probably do better than using a mutex cause it's only updated in one thread
T8b949e// and read in another, but I odn't know enough fancy rust stuff to actually do that.
T8b949e// UDP -> RNS
Tff7b72let Te6edf3udp_to_rns Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72let Tff7b72mut Te6edf3buf Tff7b72= Tb4b4b4[T79c0ff0Tff7b72u8Tb4b4b4; T79c0ff4096Tb4b4b4]Tb4b4b4;
Tff7b72loop Tb4b4b4{
Tff7b72let Te6edf3stuff Tff7b72= Te6edf3socketTb4b4b4.Te6edf3recv_fromTb4b4b4(Tff7b72&Tff7b72mut Te6edf3bufTb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tff7b72match Te6edf3stuff Tb4b4b4{
Tffa657OkTb4b4b4(Tb4b4b4(T79c0ff0Tb4b4b4,Te6edf3_Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{ Tff7b72breakTb4b4b4}Tb4b4b4,
Tffa657OkTb4b4b4(Tb4b4b4(Te6edf3nTb4b4b4,Te6edf3addrTb4b4b4)Tb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Tff7b72let Tff7b72mut Te6edf3a Tff7b72= Te6edf3client_local_port_1Tb4b4b4.Te6edf3lockTb4b4b4(Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4; Tff7b72*Te6edf3a Tff7b72= Tffa657SomeTb4b4b4(Te6edf3addrTb4b4b4.Te6edf3portTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3mux_fwdTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3DataTb4b4b4, Te6edf3sidTb4b4b4, Te6edf3bufTb4b4b4[Tff7b72..Te6edf3nTb4b4b4]Tb4b4b4.Te6edf3to_vecTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4}
Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] UDP read error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// RNS -> UDP
Tff7b72let Te6edf3rns_to_udp Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72loop Tb4b4b4{
Tff7b72if Tff7b72let Tffa657SomeTb4b4b4(Te6edf3frameTb4b4b4) Tff7b72= Te6edf3session_rxTb4b4b4.Te6edf3recvTb4b4b4(Tb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tff7b72match Te6edf3frameTb4b4b4.Te6edf3frame_type Tb4b4b4{
Te6edf3FrameType::Te6edf3Data Tff7b72=Tff7b72> Tb4b4b4{
Tff7b72let Te6edf3a Tff7b72= Te6edf3client_local_port_2Tb4b4b4.Te6edf3lockTb4b4b4(Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tff7b72let Te6edf3value Tff7b72= Tff7b72*Te6edf3aTb4b4b4;
Tff7b72if Tff7b72let Tffa657SomeTb4b4b4(Te6edf3portTb4b4b4) Tff7b72= Te6edf3value Tb4b4b4{
Tff7b72if Tff7b72let Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72= Te6edf3socket1Tb4b4b4.Te6edf3send_toTb4b4b4(Tff7b72&Te6edf3frameTb4b4b4.Te6edf3payloadTb4b4b4, Tb4b4b4(Te6edf3Ipv4Addr::Te6edf3LOCALHOSTTb4b4b4,Te6edf3portTb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] UDP write error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tb4b4b4}Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ffUDP received but client side does not know of a portTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// break // shouldn't break because this might not be the client's fault
T8b949e// maybe some random bot send a udp request to that port before the client
T8b949e// could do anything, so we just leave it open.
Tb4b4b4}
Tb4b4b4}
Te6edf3FrameType::Te6edf3Close Tff7b72=Tff7b72> Tb4b4b4{ Tff7b72breakTb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72breakTb4b4b4;
Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72let Tb4b4b4(Tff7b72mut Te6edf3tcp_readTb4b4b4, Tff7b72mut Te6edf3_tcp_writeTb4b4b4) Tff7b72= Te6edf3tcp_streamTb4b4b4.Te6edf3into_splitTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3break_connection_tcp_check Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72let Tff7b72mut Te6edf3buf Tff7b72= Tb4b4b4[T79c0ff0Tff7b72u8Tb4b4b4; T79c0ff4096Tb4b4b4]Tb4b4b4;
Tff7b72loop Tb4b4b4{
Tff7b72match Te6edf3tcp_readTb4b4b4.Te6edf3readTb4b4b4(Tff7b72&Tff7b72mut Te6edf3bufTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tffa657OkTb4b4b4(T79c0ff0Tb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6fftcp connectioned associated with udp died {:?}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}Tb4b4b4,
Tffa657OkTb4b4b4(Te6edf3nTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ffclient still sending tcp through udp port {:?} {:?}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Tff7b72&Te6edf3bufTb4b4b4[T79c0ff0Tff7b72..Te6edf3nTb4b4b4]Tb4b4b4)
Tb4b4b4}
Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] TCP read error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3tokio::Te6edf3selectTff7b72! Tb4b4b4{
Te6edf3_ Tff7b72= Te6edf3udp_to_rns Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72= Te6edf3rns_to_udp Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72= Te6edf3break_connection_tcp_check Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}
Tb4b4b4}
Te6edf3muxTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3CloseTb4b4b4, Te6edf3sidTb4b4b4, Tffa657Vec::Te6edf3newTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Te6edf3muxTb4b4b4.Te6edf3drop_sessionTb4b4b4(Te6edf3sidTb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4}
Tff7b72pub Tff7b72async Tff7b72fn Td2a8ffrelay_bidirectional_udp_server_sideTb4b4b4(
Te6edf3sid: Tffa657u32Tb4b4b4,
Te6edf3socket: T56d364tokio::Te6edf3net::Te6edf3UdpSocketTb4b4b4,
Te6edf3mux: T56d364MuxHandleTb4b4b4,
Tff7b72mut Te6edf3session_rx: T56d364mpsc::Te6edf3UnboundedReceiverTff7b72<Te6edf3FrameTff7b72>Tb4b4b4,
Te6edf3filter_config: T56d364FilterConfigTb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72let Te6edf3socket Tff7b72= Te6edf3Arc::Te6edf3newTb4b4b4(Te6edf3socketTb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3socket1 Tff7b72= Te6edf3socketTb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3config1 Tff7b72= Te6edf3Arc::Te6edf3newTb4b4b4(Te6edf3filter_configTb4b4b4)Tb4b4b4; T8b949e// someone please figure out a better way of doing this
Tff7b72let Te6edf3config2 Tff7b72= Te6edf3config1Tb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3mux_fwd Tff7b72= Te6edf3muxTb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// UDP -> RNS
Tff7b72let Te6edf3udp_to_rns Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72let Tff7b72mut Te6edf3buf Tff7b72= Tb4b4b4[T79c0ff0Tff7b72u8Tb4b4b4; T79c0ff4096Tb4b4b4]Tb4b4b4;
Tff7b72loop Tb4b4b4{
Tff7b72let Te6edf3stuff Tff7b72= Te6edf3socketTb4b4b4.Te6edf3recv_fromTb4b4b4(Tff7b72&Tff7b72mut Te6edf3bufTb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tff7b72match Te6edf3stuff Tb4b4b4{
Tffa657OkTb4b4b4(Tb4b4b4(T79c0ff0Tb4b4b4,Te6edf3_Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{ Tff7b72breakTb4b4b4}Tb4b4b4,
Tffa657OkTb4b4b4(Tb4b4b4(Te6edf3nTb4b4b4,Te6edf3addrTb4b4b4)Tb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Tff7b72if Te6edf3allowed_ipTb4b4b4(Te6edf3addrTb4b4b4, Tff7b72&Te6edf3config1Tb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tff7b72let Tff7b72mut Te6edf3packet Tff7b72= Te6edf3new_udp_headerTb4b4b4(Te6edf3addrTb4b4b4)Tb4b4b4.Te6edf3expectTb4b4b4(Ta5d6ff"Ta5d6ffcannot wrap udp packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3extend_from_sliceTb4b4b4(Tff7b72&Te6edf3bufTb4b4b4[Tff7b72..Te6edf3nTb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3mux_fwdTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3DataTb4b4b4, Te6edf3sidTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3to_vecTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ffpacket came from illegal server locationTa5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] UDP read error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// RNS -> UDP
Tff7b72let Te6edf3rns_to_udp Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72loop Tb4b4b4{
Tff7b72if Tff7b72let Tffa657SomeTb4b4b4(Te6edf3frameTb4b4b4) Tff7b72= Te6edf3session_rxTb4b4b4.Te6edf3recvTb4b4b4(Tb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tff7b72match Te6edf3frameTb4b4b4.Te6edf3frame_type Tb4b4b4{
Te6edf3FrameType::Te6edf3Data Tff7b72=Tff7b72> Tb4b4b4{
Tff7b72match Te6edf3parse_udp_requestTb4b4b4(Tff7b72&Tff7b72*Te6edf3frameTb4b4b4.Te6edf3payloadTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tffa657OkTb4b4b4(Tb4b4b4(Te6edf3_fragTb4b4b4,Te6edf3addrTb4b4b4,Te6edf3dataTb4b4b4)Tb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Tff7b72if Tff7b72let Tffa657SomeTb4b4b4(Te6edf3socketTb4b4b4) Tff7b72= Te6edf3filter_and_convertTb4b4b4(Te6edf3addrTb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4, Tffa657SomeTb4b4b4(Tff7b72&Te6edf3config2Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tff7b72if Tff7b72let Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72= Te6edf3socket1Tb4b4b4.Te6edf3send_toTb4b4b4(Te6edf3dataTb4b4b4,Te6edf3socketTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] UDP write error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] client attempted to send to illegal location {}Ta5d6ff"Tb4b4b4,Te6edf3sidTb4b4b4, Te6edf3addrTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] UDP read error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72break
Tb4b4b4}
Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Te6edf3FrameType::Te6edf3Close Tff7b72=Tff7b72> Tb4b4b4{ Tff7b72breakTb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72breakTb4b4b4;
Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3tokio::Te6edf3selectTff7b72! Tb4b4b4{
Te6edf3_ Tff7b72= Te6edf3udp_to_rns Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72= Te6edf3rns_to_udp Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Tb4b4b4}
Te6edf3muxTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3CloseTb4b4b4, Te6edf3sidTb4b4b4, Tffa657Vec::Te6edf3newTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Te6edf3muxTb4b4b4.Te6edf3drop_sessionTb4b4b4(Te6edf3sidTb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4}
T8b949e/// udp must still have an associated tcp connection to detect when the connection is over.
T8b949e/// this does not apply to the server (as in rns server) as it detects that the frame is being closed
T8b949e/// udp doesn't have a connetcion so the server cannot detect that the remote server the client is connecting
T8b949e/// to is offline per say.
T8b949e///
T8b949e/// basically, the client can stop the udp connection either by the reticulum link breaking
T8b949e/// OR the process using the udp connection stops
T8b949e/// while the server only stops in the first scenario because the server cannot know if the remote
T8b949e/// server not responding is part of the protocol.
Tff7b72pub Tff7b72async Tff7b72fn Td2a8ffrelay_forwarded_tcpTb4b4b4(
Te6edf3sid: Tffa657u32Tb4b4b4,
Te6edf3stream: T56d364tokio::Te6edf3net::Te6edf3TcpStreamTb4b4b4, T8b949e// stream between local forwarded port and the port
T8b949e// of whatever application is connecting to it.
Te6edf3mux: T56d364MuxHandleTb4b4b4,
Tff7b72mut Te6edf3session_rx: T56d364mpsc::Te6edf3UnboundedReceiverTff7b72<Te6edf3FrameTff7b72>Tb4b4b4)
Tb4b4b4{
Tff7b72let Tb4b4b4(Tff7b72mut Te6edf3tcp_readTb4b4b4, Tff7b72mut Te6edf3tcp_writeTb4b4b4) Tff7b72= Te6edf3streamTb4b4b4.Te6edf3into_splitTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3mux_fwd Tff7b72= Te6edf3muxTb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ffrelay forwarded tcpTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// TCP -> RNS
Tff7b72let Te6edf3tcp_to_rns Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72let Tff7b72mut Te6edf3buf Tff7b72= Tb4b4b4[T79c0ff0Tff7b72u8Tb4b4b4; T79c0ff4096Tb4b4b4]Tb4b4b4;
Tff7b72loop Tb4b4b4{
Tff7b72match Te6edf3tcp_readTb4b4b4.Te6edf3readTb4b4b4(Tff7b72&Tff7b72mut Te6edf3bufTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tffa657OkTb4b4b4(T79c0ff0Tb4b4b4) Tff7b72=Tff7b72> Tff7b72breakTb4b4b4,
Tffa657OkTb4b4b4(Te6edf3nTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3mux_fwdTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3DataTb4b4b4, Te6edf3sidTb4b4b4, Te6edf3bufTb4b4b4[Tff7b72..Te6edf3nTb4b4b4]Tb4b4b4.Te6edf3to_vecTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4}
Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] TCP read error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// RNS -> TCP
Tff7b72let Te6edf3rns_to_tcp Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72while Tff7b72let Tffa657SomeTb4b4b4(Te6edf3frameTb4b4b4) Tff7b72= Te6edf3session_rxTb4b4b4.Te6edf3recvTb4b4b4(Tb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tff7b72match Te6edf3frameTb4b4b4.Te6edf3frame_type Tb4b4b4{
Te6edf3FrameType::Te6edf3Data Tff7b72=Tff7b72> Tb4b4b4{
Tff7b72if Tff7b72let Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72= Te6edf3tcp_writeTb4b4b4.Te6edf3write_allTb4b4b4(Tff7b72&Te6edf3frameTb4b4b4.Te6edf3payloadTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] TCP write error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3FrameType::Te6edf3Close Tff7b72=Tff7b72> Tff7b72breakTb4b4b4,
Te6edf3FrameType::Te6edf3ConnectErr Tff7b72=Tff7b72> Tb4b4b4{Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ffconnection errored, should probably be handled by different codeTa5d6ff"Tb4b4b4)Tb4b4b4; Tff7b72breakTb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3tokio::Te6edf3selectTff7b72! Tb4b4b4{
Te6edf3_ Tff7b72= Te6edf3tcp_to_rns Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72= Te6edf3rns_to_tcp Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Tb4b4b4}
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] tcp relay endedTa5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4)Tb4b4b4;
Te6edf3muxTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3CloseTb4b4b4, Te6edf3sidTb4b4b4, Tffa657Vec::Te6edf3newTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Te6edf3muxTb4b4b4.Te6edf3drop_sessionTb4b4b4(Te6edf3sidTb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4}
Tff7b72pub Tff7b72async Tff7b72fn Td2a8ffrelay_forwarded_udpTb4b4b4(
Te6edf3sid: Tffa657u32Tb4b4b4,
Te6edf3stream: T56d364UdpStreamTb4b4b4, T8b949e// stream between local forwarded port and the port
T8b949e// of whatever application is connecting to it.
Te6edf3mux: T56d364MuxHandleTb4b4b4,
Tff7b72mut Te6edf3session_rx: T56d364mpsc::Te6edf3UnboundedReceiverTff7b72<Te6edf3FrameTff7b72>Tb4b4b4,
Te6edf3server_port: Tffa657u16Tb4b4b4)
Tb4b4b4{
Tff7b72let Te6edf3mux_fwd Tff7b72= Te6edf3muxTb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72let Te6edf3localhost_server_addr Tff7b72= Tb4b4b4(Te6edf3Ipv4Addr::Te6edf3LOCALHOSTTb4b4b4, Te6edf3server_portTb4b4b4)Tb4b4b4.Te6edf3to_target_addrTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3unwrapTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72let Tb4b4b4(Tff7b72mut Te6edf3udp_readTb4b4b4,Tff7b72mut Te6edf3udp_writeTb4b4b4) Tff7b72= Te6edf3tokio::Te6edf3io::Te6edf3splitTb4b4b4(Te6edf3streamTb4b4b4)Tb4b4b4;
T8b949e// UDP -> RNS
Tff7b72let Te6edf3tcp_to_rns Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72let Tff7b72mut Te6edf3buf Tff7b72= Tb4b4b4[T79c0ff0Tff7b72u8Tb4b4b4; T79c0ff4096Tb4b4b4]Tb4b4b4;
Tff7b72loop Tb4b4b4{
Tff7b72match Te6edf3udp_readTb4b4b4.Te6edf3readTb4b4b4(Tff7b72&Tff7b72mut Te6edf3bufTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tffa657OkTb4b4b4(T79c0ff0Tb4b4b4) Tff7b72=Tff7b72> Tff7b72breakTb4b4b4,
Tffa657OkTb4b4b4(Te6edf3nTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Tff7b72let Tff7b72mut Te6edf3packet Tff7b72= Te6edf3new_udp_headerTb4b4b4(Te6edf3localhost_server_addrTb4b4b4.Te6edf3cloneTb4b4b4(Tb4b4b4) Tb4b4b4)Tb4b4b4.Te6edf3expectTb4b4b4(Ta5d6ff"Ta5d6ffcannot wrap udp packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3extend_from_sliceTb4b4b4(Tff7b72&Te6edf3bufTb4b4b4[Tff7b72..Te6edf3nTb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3mux_fwdTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3DataTb4b4b4, Te6edf3sidTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3to_vecTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4}
Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] TCP read error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// RNS -> UDP
Tff7b72let Te6edf3rns_to_tcp Tff7b72= Te6edf3tokio::Te6edf3spawnTb4b4b4(Tff7b72async Tff7b72move Tb4b4b4{
Tff7b72while Tff7b72let Tffa657SomeTb4b4b4(Te6edf3frameTb4b4b4) Tff7b72= Te6edf3session_rxTb4b4b4.Te6edf3recvTb4b4b4(Tb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tff7b72match Te6edf3frameTb4b4b4.Te6edf3frame_type Tb4b4b4{
Te6edf3FrameType::Te6edf3Data Tff7b72=Tff7b72> Tb4b4b4{
Tff7b72match Te6edf3parse_udp_requestTb4b4b4(Tff7b72&Tff7b72*Te6edf3frameTb4b4b4.Te6edf3payloadTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Tffa657OkTb4b4b4(Tb4b4b4(Te6edf3_fragTb4b4b4,Te6edf3_addrTb4b4b4,Te6edf3dataTb4b4b4)Tb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
T8b949e// let target = addr.into_string_and_port();
Tff7b72if Tff7b72let Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72= Te6edf3udp_writeTb4b4b4.Te6edf3write_allTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] UDP write error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tb4b4b4}
Tb4b4b4}
Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72=Tff7b72> Tb4b4b4{
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] UDP read error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72break
Tb4b4b4}
Tb4b4b4}Tb4b4b4;
Tff7b72if Tff7b72let Tffa657ErrTb4b4b4(Te6edf3eTb4b4b4) Tff7b72= Te6edf3udp_writeTb4b4b4.Te6edf3write_allTb4b4b4(Tff7b72&Te6edf3frameTb4b4b4.Te6edf3payloadTb4b4b4)Tb4b4b4.Tff7b72await Tb4b4b4{
Te6edf3warnTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] TCP write error: {}Ta5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3FrameType::Te6edf3Close Tff7b72=Tff7b72> Tff7b72breakTb4b4b4,
Te6edf3_ Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3tokio::Te6edf3selectTff7b72! Tb4b4b4{
Te6edf3_ Tff7b72= Te6edf3tcp_to_rns Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Te6edf3_ Tff7b72= Te6edf3rns_to_tcp Tff7b72=Tff7b72> Tb4b4b4{Tb4b4b4}Tb4b4b4,
Tb4b4b4}
Te6edf3debugTff7b72!Tb4b4b4(Ta5d6ff"Ta5d6ff[{}] udp relay endedTa5d6ff"Tb4b4b4, Te6edf3sidTb4b4b4)Tb4b4b4;
Te6edf3muxTb4b4b4.Te6edf3sendTb4b4b4(Te6edf3FrameType::Te6edf3CloseTb4b4b4, Te6edf3sidTb4b4b4, Tffa657Vec::Te6edf3newTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Te6edf3muxTb4b4b4.Te6edf3drop_sessionTb4b4b4(Te6edf3sidTb4b4b4)Tb4b4b4.Tff7b72awaitTb4b4b4;
Tb4b4b4}
Served by rngit 1.5.1 - Generated in 0.11s